﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Applications.Common;
using System.IO;
using System.Windows.Media.Imaging;

using Microsoft.Phone.Controls.Primitives;
using System.Threading;
using Microsoft.Xna.Framework.Media;
using System.ComponentModel;
using System.Windows.Navigation;
using Classes;
using System.Collections.ObjectModel;

namespace MemoBoss
{
    public partial class CollectionScreen : UserControl
    {
        Action returnMethod;
        Action SetBackgroundPicture;
        public CollectionScreen(Action callback, Action SetBGPicture)
            : base()
        {
            SetBackgroundPicture = SetBGPicture;
            returnMethod = callback;
            InitializeComponent();
            //lbPictures.ItemsSource = PicturesList;
            //lbAlbums.ItemsSource = AlbumsList;
            ImagesLoadingBar.Visibility = System.Windows.Visibility.Collapsed;
            AlbumsLoadingBar.Visibility = System.Windows.Visibility.Collapsed;

        }






        private delegate void NewImagesHandler();
        private void Panorama_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (galleryPanorama.SelectedItem == panItemPictures)
            {
                loadTiles(false);
            }
            else
            {
                loadTiles(true);
            }
        }
        private void loadTiles(bool AlbumsOrPictures)
        {

            //ThreadPool.QueueUserWorkItem(delegate(object notUsed)
            //{
            //    NewImagesHandler newImageHandler;
            //    //LoadPictures();
            //    if (AlbumsOrPictures)
            //    {
            //        newImageHandler = new NewImagesHandler(LoadAlbums);
            //    }
            //    else
            //    {
            //        newImageHandler = new NewImagesHandler(LoadPictures);
            //    }
            //    object[] args = { };

            //    this.Dispatcher.BeginInvoke(newImageHandler, args);

            //});
            if (backgroundWorker != null && backgroundWorker.IsBusy)
            {
                backgroundWorker.CancelAsync();
                AlbumsLoadingBar.Visibility = System.Windows.Visibility.Collapsed;
                ImagesLoadingBar.Visibility = System.Windows.Visibility.Collapsed;
            }
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.WorkerSupportsCancellation = true;
            backgroundWorker.DoWork +=
                (s, e) =>
                {

                    // runs on background thread
                    if (AlbumsOrPictures)
                    {
                        Dispatcher.BeginInvoke(() =>
                        {
                            lbPictures.Visibility = System.Windows.Visibility.Collapsed;
                        });
                        LoadAlbums();
                    }
                    else
                    {
                        Dispatcher.BeginInvoke(() =>
                        {
                            lbAlbums.Visibility = System.Windows.Visibility.Collapsed;
                        });
                        LoadPictures();
                    }

                };


            backgroundWorker.RunWorkerAsync();

        }
        BackgroundWorker backgroundWorker;
        //protected override void OnNavigatedTo(NavigationEventArgs e)
        //{
        //    base.OnNavigatedTo(e);
        //    loadTiles(true);
        // //  loadTiles(false);
        //}
        //private void HideAlbums()
        //{

        //    foreach (AlbumTile alb in TileGridAlbums.Children)
        //    {
        //        alb.HideAnimation.Begin();
        //    }
        //}
        //private void HidePictures()
        //{
        //    //foreach (PictureTile pic in TileGridPictures.Children)
        //    //{
        //    //    //pic.HideAnimation.Begin();
        //    //    pic.Opacity = 0;
        //    //}

        //}
        public class ImageData : INotifyPropertyChanged
        {

            public int hashcode { get; set; }
            private Visibility _include;
            public Visibility Include
            {
                get
                {
                    return _include;
                }
                set
                {
                    _include = value;
                    NotifyPropertyChanged("Include");
                }
            }
            private ImageSource _imageSource;
            public ImageSource ImageSource
            {
                get
                {
                    return _imageSource;
                }
                set
                {
                    _imageSource = value;
                    // NotifyPropertyChanged("ImageSource");
                }
            }
            public int index { get; set; }
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(String propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
        public class AlbumData : INotifyPropertyChanged
        {

            public int hashcode { get; set; }
            public string AlbumName { get; set; }
            private Visibility _include;
            public Visibility Include
            {
                get
                {
                    return _include;
                }
                set
                {
                    _include = value;
                    NotifyPropertyChanged("Include");
                }
            }
            private ImageSource _imageSource;
            public ImageSource ImageSource
            {
                get
                {
                    return _imageSource;
                }
                set
                {
                    _imageSource = value;
                    // NotifyPropertyChanged("ImageSource");
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(String propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

        private ImageSource createImgSource(Stream picstream)
        {
            BitmapImage bi = new BitmapImage();

            bi.SetSource(picstream);
            return bi;
        }

        public void LoadThumbAsync(ImageData id, Stream src,
                    WriteableBitmap bmp, object argument)
        {
            ThreadPool.QueueUserWorkItem(callback =>
            {
                bmp.LoadJpeg(src);
                src.Dispose();

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    id.ImageSource = bmp;
                });
                //if (ImageLoaded != null)  
                //{  
                //    Deployment.Current.Dispatcher.BeginInvoke(() =>  
                //    {  
                //        ImageLoaded(bmp, argument);  
                //    });  
                //}  
            });
        }



        ObservableCollection<ImageData> PicturesList;
        ObservableCollection<AlbumData> AlbumsList;
        //WriteableBitmap bmp = new WriteableBitmap(100, 100);
        private void LoadPictures()
        {
            if (picturesLoaded)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    lbPictures.Visibility = System.Windows.Visibility.Visible;

                });
                return;
            }

            PicturesList = new ObservableCollection<ImageData>();
            Dispatcher.BeginInvoke(() =>
            {
                lbPictures.Visibility = System.Windows.Visibility.Visible;
                ImagesLoadingBar.Visibility = System.Windows.Visibility.Visible;
                ImagesProgressTransform.ScaleX = 0;
                lbPictures.ItemsSource = PicturesList;
            });


            var ml = new Microsoft.Xna.Framework.Media.MediaLibrary();

            using (var pictures = ml.Pictures)
            {
                List<Picture> picturelist = ml.Pictures.ToList();

                var test = pictures.Where(x => App.collection.AlbumCollection.ContainsKey(x.Album.GetHashCode())).OrderBy(x => x.Album.Name).ThenBy(x => x.Date);

                int cnt = test.Count();
                WriteableBitmap[] bmp = new WriteableBitmap[cnt];
                Dispatcher.BeginInvoke(() =>
                {
                    lock (bmp)
                    {
                        for (int i = 0; i != (bmp.Length); i++)
                        {
                            if (backgroundWorker.CancellationPending) return;
                            bmp[i] = new WriteableBitmap(100, 100);
                        }
                    }
                });

                Thread.Sleep(200);
                if (backgroundWorker.CancellationPending) return;
                lock (bmp)
                {
                    int index = 0;
                    foreach (var tst in test)
                    {
                        if (backgroundWorker.CancellationPending) return;
                        ImageData item = new ImageData();
                        var img = tst;
                        Stream src = tst.GetThumbnail();
                        bmp[index].LoadJpeg(src);
                        src.Dispose();

                        item.ImageSource = bmp[index];
                        //item.ImageSource = bmp;
                        // LoadThumbAsync(item, img.GetThumbnail(), bmp, this);

                        item.hashcode = img.GetHashCode();
                        item.Include = App.collection.PicturesCollection.ContainsKey(item.hashcode) ? Visibility.Visible : Visibility.Collapsed;
                        item.index = picturelist.IndexOf(img);
                        index++;
                        Dispatcher.BeginInvoke(() =>
                         {
                             ImagesProgressTransform.ScaleX = (double)index / cnt;
                             PicturesList.Add(item);
                         });


                    }
                }
            }
            picturesLoaded = true;
            Dispatcher.BeginInvoke(() =>
                        {
                            ImagesLoadingBar.Visibility = System.Windows.Visibility.Collapsed;
                        });
        }
        public static bool picturesLoaded = false;
        private void LoadAlbums()
        {
            if (albumsLoaded)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    lbAlbums.Visibility = System.Windows.Visibility.Visible;
                });
                return;
            }

            AlbumsList = new ObservableCollection<AlbumData>();
            Dispatcher.BeginInvoke(() =>
            {
                lbAlbums.Visibility = System.Windows.Visibility.Visible;
                AlbumsLoadingBar.Visibility = System.Windows.Visibility.Visible;
                AlbumsProgressTransform.ScaleX = 0;
                lbAlbums.ItemsSource = AlbumsList;
            });


            var ml = new Microsoft.Xna.Framework.Media.MediaLibrary();

            using (var alb = ml.RootPictureAlbum.Albums)
            {
                //List<Picture> albumlist = ml.Pictures.ToList();

                var albums = alb.Where(a => a.Pictures.Count > 0).ToList();

                int cnt = albums.Count();
                WriteableBitmap[] bmp = new WriteableBitmap[cnt];
                Dispatcher.BeginInvoke(() =>
                {
                    lock (bmp)
                    {
                        for (int i = 0; i != (bmp.Length); i++)
                        {
                            if (backgroundWorker.CancellationPending) return;
                            bmp[i] = new WriteableBitmap(100, 100);
                        }
                    }
                });

                Thread.Sleep(200);
                if (backgroundWorker.CancellationPending) return;
                lock (bmp)
                {
                    int index = 0;
                    foreach (var album in albums)
                    {
                        if (backgroundWorker.CancellationPending) return;
                        AlbumData item = new AlbumData();
                        //var img = tst;
                        Stream src = album.Pictures.First().GetThumbnail();
                        bmp[index].LoadJpeg(src);
                        src.Dispose();

                        item.ImageSource = bmp[index];


                        item.hashcode = album.GetHashCode();
                        item.Include = App.collection.AlbumCollection.ContainsKey(item.hashcode) ? Visibility.Visible : Visibility.Collapsed;

                        item.AlbumName = album.Name;
                        index++;
                        Dispatcher.BeginInvoke(() =>
                        {
                            AlbumsProgressTransform.ScaleX = (double)index / cnt;
                            AlbumsList.Add(item);
                        });


                    }
                }
            }
            albumsLoaded = true;
            Dispatcher.BeginInvoke(() =>
            {
                AlbumsLoadingBar.Visibility = System.Windows.Visibility.Collapsed;
            });
            //AlbumsList = new ObservableCollection<AlbumData>();
            //var ml = new Microsoft.Xna.Framework.Media.MediaLibrary();
            //using (var alb = ml.RootPictureAlbum.Albums)
            //{
            //    var albums = alb.Where(a => a.Pictures.Count > 0).ToList();

            //    List<Picture> albumslist = ml.Pictures.ToList();

            //    foreach (var tst in albums)
            //    {
            //        AlbumData item = new AlbumData();
            //        var album = tst;
            //        Dispatcher.BeginInvoke(() =>
            //           {
            //               item.ImageSource = createImgSource(album.Pictures.First().GetThumbnail());
            //           });
            //        item.hashcode = album.GetHashCode();
            //        item.Include = App.collection.AlbumCollection.ContainsKey(item.hashcode) ? Visibility.Visible : Visibility.Collapsed;
            //        item.AlbumName = album.Name;

            //        Dispatcher.BeginInvoke(() =>
            //         {
            //             AlbumsList.Add(item);
            //         });
            //    }

            //    Dispatcher.BeginInvoke(() =>
            //    {
            //        lbAlbums.ItemsSource = AlbumsList;
            //    });
            //}

        }
        public static bool albumsLoaded = false;
        private void btnSave_Click(object sender, EventArgs e)
        {
            App.collection.Save();
        }

        //private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
        //{
        //    galleryPanorama.ApplyTemplate();
        //    initLayers();

        //}
        private void Show_Completed(object sender, EventArgs e)
        {
            
            lbPictures.Visibility = System.Windows.Visibility.Collapsed;

            int curIndex = 1;
            (galleryPanorama.Items[curIndex] as PanoramaItem).Visibility = Visibility.Collapsed;
            galleryPanorama.SetValue(Panorama.SelectedItemProperty, galleryPanorama.Items[(curIndex + 1) % galleryPanorama.Items.Count]);
            galleryPanorama.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            (galleryPanorama.Items[curIndex] as PanoramaItem).Visibility = Visibility.Visible;

            SetBackgroundPicture();
            loadTiles(true);

        }

        private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
        {

        }
        //protected override void OnBackKeyPress(CancelEventArgs e)
        //{
        //    //base.OnBackKeyPress(e);
        //    e.Cancel = true;
        //    NavigationService.GoBack();

        //}

        public void ExitScreen()
        {
            App.collection.Save();
            this.Hide.Begin();
        }

        private void lbPictures_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lbPictures.SelectedItem != null)
            {
                ImageData item = ((ImageData)lbPictures.SelectedItem);
                item.Include = item.Include == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
                if (item.Include == Visibility.Visible)
                {
                    App.collection.PicturesCollection.Add(item.hashcode, item.index);
                }
                else
                    App.collection.PicturesCollection.Remove(item.hashcode);
            }

            lbPictures.SelectedItem = null;
        }

        private void PictureTile_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {


        }

        private void lbAlbums_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lbAlbums.SelectedItem != null)
            {
                picturesLoaded = false;
                AlbumData item = ((AlbumData)lbAlbums.SelectedItem);
                item.Include = item.Include == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
                if (item.Include == Visibility.Visible)
                {
                    App.collection.AlbumCollection.Add(item.hashcode, item.AlbumName);
                    var ml = new Microsoft.Xna.Framework.Media.MediaLibrary();

                    using (var alb = ml.RootPictureAlbum.Albums)
                    {
                        List<Picture> mlpList = ml.Pictures.ToList();
                        var pics = alb.Single(x => x.GetHashCode() == item.hashcode).Pictures;
                        foreach (Picture pic in pics)
                        {
                            try
                            {
                                App.collection.PicturesCollection.Add(pic.GetHashCode(), (int)mlpList.IndexOf(pic));
                            }
                            catch (Exception ex)
                            {
                                //TODO: logging
                            }
                        }
                    }
                }
                else
                {
                    App.collection.AlbumCollection.Remove(item.hashcode);
                    var ml = new Microsoft.Xna.Framework.Media.MediaLibrary();
                    using (var alb = ml.RootPictureAlbum.Albums)
                    {
                        var pics = alb.Single(x => x.GetHashCode() == item.hashcode).Pictures;
                        foreach (Picture pic in pics)
                        {
                            App.collection.PicturesCollection.Remove(pic.GetHashCode());
                        }
                    }
                }

            }

            lbAlbums.SelectedItem = null;
        }
    }
}